package Algorithm.Array.SpiralMatrix;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ClockwiseSpiralOrderMatrixPrint
 * @Description TODO: 这里填写类的描述
 * @Author ykeezy
 * @Date 2024/7/5 15:04
 */
//给你一个 m 行 n 列的矩阵 matrix ，请按照 顺时针螺旋顺序 ，返回矩阵中的所有元素。

    //解题时需要注意这是一个 m行n列的矩阵，需要弄清楚m行n列的边界条件（循环次数等）
    //与生成n*n螺旋数组不同的是，由于m与n是任意正整数，所以产生的边界条件也会比较多
public class ClockwiseSpiralOrderMatrixPrint {
    public static void main(String[] args) {
        List<Integer> result = spiralOrder(new int[][]{{1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20}});
        for (int cols = 0; cols < result.size(); cols++) {
            System.out.print(result.get(cols) + " ");
        }
    }

    public static List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<>();
        //行数
        int rows = matrix.length;
        //列数
        int cols = matrix[0].length;
        //偏移量
        int offset = 1;
        //每次循环的开始坐标X,Y
        int startY = 0;
        int startX = 0;
        int x = 0;
        int y = 0;
        //循环的次数times
        int times = 0;
        //两个boolean分别判断本次循环是否有行或列没有被遍历，若行没有被遍历，说明只剩一列，若列没有被遍历，说明只剩一行
        boolean isColSearch = false;
        boolean isRowSearch = false;
        //timesEdge是循环这个矩阵的最大次数，这个次数总是为 min(row, col) / 2向上取整的结果
        double timesEdge = Math.min(rows, cols);
        //结果向上取整
        timesEdge = Math.ceil(timesEdge / 2);
        //若rows==1说明只有一行，直接单独对这行进行收集
        if (rows == 1) {
            for (int i = 0; i < cols; i++) {
                list.add(matrix[0][i]);

            }
            return list;

        }
        //若cols==1说明只有一列，直接单独对这列进行收集
        if (cols == 1){
            for (int j = 0; j < rows; j++) {
                list.add(matrix[j][0]);

            }

            return list;

        }

        //顺时针循环体，每个for代表一条边的遍历
        while(times < timesEdge){
            isColSearch = false;
            isRowSearch = false;
            x = startX;
            y = startY;
            for (;x < cols- offset; x++) {
                isRowSearch = true;
                list.add(matrix[y][x]);

            }

            for (;y < rows - offset; y++){
                isColSearch = true;
                list.add(matrix[y][x]);

            }

            for (;x >= offset ; x--) {
                list.add(matrix[y][x]);
                //若rows已无需扫描，则说明当行已从左到右收集，无需再从右到左收集一次
                if (! isColSearch){
                    break;

                }

            }

            for (;y >= offset ; y--) {
                list.add(matrix[y][x]);
                //若cols已无需扫描，则说明当列已从上到下收集，无需从下到上再收集一次
                if (! isRowSearch){
                    break;

                }

            }

            offset++;
            startY = y + 1;
            startX = x + 1;
            times++;

        }

        //rows == cols 且为奇数时矩阵的会空出一格，判断补上
        if (cols % 2 == 1 && cols == rows){
            list.add(matrix[rows / 2][rows / 2]);

        }

        return list;

    }
}
